package cn.gjxblog.scheduling.spring.cron;

import cn.gjxblog.base.DateUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.scheduling.support.CronSequenceGenerator;

import java.util.Date;

@RunWith(JUnit4.class)
public class TestCronSequenceGenerator {

    /**
     * Spring对Corn 表达式支持的核心组件
     */
    CronSequenceGenerator generator;

    /**
     * 校验表达式是否合法
     * Spring corn 表达式共6位
     * 支持的通配符有
     *
     *
     *  *  *  *  *  *  *
     * 秒 分 时   日 月 周
     *
     * 秒 0-59
     * 分 0-59
     * 时 0-23
     * 日 1-31
     * 月 1-12
     * 周  1-7
     *
     * 支持的通配符有
     * , - * / ？
     *
     * ，代表和  如1,2 可以表示1号和2号
     * - 代表区间  如1-31 可以表示1号到31号
     * * 代表所有  如在月位 可以表示 每年的所有月
     * / 表示递增  如在分位 0/5 可以表示每5分钟执行一次
     * ?  代表不关心  ？ 在周位可以表示不关心周几
     */
    @Test
    public void test1(){
        validExpression("0 0 * * * * * *");
        validExpression("0 0 * * * *");
        validExpression("* * * * * * *");
        validExpression("* * * * * *");
        validExpression("* * * * * * *");
        validExpression("*/5 * * * * ?");


    }

    private void validExpression(String expression) {
        System.out.println(expression+" 是" + (CronSequenceGenerator.isValidExpression(expression)==true?"有效":"无效的"));
    }

    /**
     * 根据设定时间和corn表达式，推断下次执行时间
     */
    @Test
    public void test2(){
        // 每秒执行一次
        printNextDate("* * * * * *");
        // 每分钟执行一次
        printNextDate("0 * * * * *");
        // 每小时执行一次
        printNextDate("0 0 * * * *");
        // 每分钟的第10秒执行一次
        printNextDate("10 * * * * *");
        // 每天8-10点 每小时执行一次
        printNextDate("0 0 8-10 * * *");
        // 每隔5秒执行一次
        printNextDate("*/5 * * * * ?");
        //每个月1号执行一次
        printNextDate("0 0 0 1 * *");
        //每年1月1号执行一次
        printNextDate("0 0 0 1 1 *");
        // 最后一位代表周，每个周一的凌晨执行一次。
        printNextDate("0 0 0 * * 1");

        // 每个月的1号凌晨执行
        printNextDate("0 0 0 1 * *");
        printNextDate("0 0 0 1 * ?");

        // 每年的三月15号的8-10点，每隔5分钟执行
        printNextDate("0 0/5 8-10 15 3 ?");
        printNextDate("0 0/5 8-10 15 3 *");

        // 每个月的周一 10点开始，每隔30秒执行
        printNextDate("0/30 * 10 * * 1");

        // 每个月的1号和2号执行一次
        printNextDate("0 0 0 1,2 * ?");

        printNextDate("0 * * * * ?");





    }

    private void printNextDate(String expression) {
        System.out.print(expression +": ");
        generator = new CronSequenceGenerator(expression);
        int i = 0;
        Date lastDate = new Date();
        do {
            System.out.print(DateUtils.formatDate(lastDate) +",");
            lastDate = generator.next(lastDate);
            i++;
        }while (i < 5);
        System.out.println();
    }
}
